package backend;

import java.util.LinkedList;
import java.util.Queue;


/**
 * SharedMemory.java
 * 
 * Simulates Shared Memory for hardware.
 * 
 * @author BitWiseGuys Dallas Rosson, Joshua Warner, Tyson Lewis, Ken Norton
 * @version 1.0, 5/27/2012
 */
public class SharedMemory {
	
	private Queue<PCB> mutex_waiting_queue; 
	
	/**
	 * True = locked.
	 * False = unlocked.
	 * */
	private boolean mutex_lock;
	
	private PCB mutex_lock_owner;
	
	private int memory;

	public SharedMemory(){
		mutex_waiting_queue = new LinkedList<PCB>();
		mutex_lock = false;
		memory = 0;
	}
	/**
	 * Sets the owner of the PCB
	 * @param the_owner takes a parameter of type PCB
	 * */
	public void setMutexLockOwner(PCB the_owner){
		if (the_owner != null){
			mutex_lock_owner = the_owner;
		}
	}
	public boolean isLocked(){
		return mutex_lock;
	}

	public void lock_mutex (){
		mutex_lock = true;
	}
	
	public void unlock_mutex (){
		mutex_lock = false;
	}
	public PCB getLockOwner(){
		return mutex_lock_owner;
	}
	
	/**
	 * @param the_value takes a parameter of type int
	 * @param the_pcb takes a type of PCB
	 * **/
	public void setMemory(int the_value, PCB the_pcb){
		if (mutex_lock==false){
			
			memory = the_value;
		}else {
			mutex_waiting_queue.offer(the_pcb);
				
		}
	
	}
	public int getMemory(){
		int result = 0;
		result = this.memory;
		return result;
	}
	/**
	 * @param the_PCB takes a parameter of type PCB.
	 * */
	public void addToWaitingQ(PCB the_PCB){
		mutex_waiting_queue.offer(the_PCB);
	}
	/**
	 * must check if it is null
	 * */
	public PCB getWaitingPCB(){
	
		return mutex_waiting_queue.poll();
		
	}
	/**
	 * creates a string with the process id's waiting for this IO
	 * @return the String of ids.
	 */
	public String getWaitinglist(){
		StringBuffer sb = new StringBuffer();
		String output = "";
		if (!mutex_waiting_queue.isEmpty()){
		for(PCB pcb: mutex_waiting_queue){
			sb.append(pcb.getPid() + ", ");
		}
		if (sb.length() > 2){
			output = sb.substring(0, sb.length() - 2);
		}
	}
		return output;
	}

	public String getMemoryString(){
		String result = "";
		result = String.valueOf(this.memory);
		return result;
	}
	public String getMutexOwnerString(){
		String result = "";
		if (mutex_lock_owner != null){
			result = String.valueOf(this.mutex_lock_owner.getPid());
		}
		return result;
	}
	public boolean isEmpty(){
		return mutex_waiting_queue.isEmpty();
	}
}


